#include"conv.h"
#include"compute.h"

void top(volatile At* in1,volatile At* in2,volatile Ot* out,int fsize,int ch_in,int ch_out,int pool){
#pragma HLS INTERFACE m_axi depth=1600 port=in1 offset=slave bundle=IN1
#pragma HLS INTERFACE m_axi depth=1600 port=in2 offset=slave bundle=IN2
#pragma HLS INTERFACE m_axi depth=8*144 port=out offset=slave bundle=OUT
#pragma HLS INTERFACE s_axilite port=return bundle=CTRL
#pragma HLS INTERFACE s_axilite port=fsize bundle=CTRL
#pragma HLS INTERFACE s_axilite port=ch_in bundle=CTRL
#pragma HLS INTERFACE s_axilite port=ch_out bundle=CTRL
#pragma HLS INTERFACE s_axilite port=pool bundle=CTRL

	const Wt weight[M][N][K][K]={
#include"weight.h"
	};
	Ot obuffer1[Tm][MAX_LEN*MAX_LEN];
	Ot obuffer2[Tm][MAX_LEN*MAX_LEN];
#pragma HLS array_partition variable=obuffer1 complete dim=1
#pragma HLS array_partition variable=obuffer2 complete dim=1
#pragma HLS RESOURCE variable=obuffer1 core=RAM_2P_BRAM
#pragma HLS RESOURCE variable=obuffer2 core=RAM_2P_BRAM
    //
    compute_one_block(in1,in2,weight,obuffer1,fsize,ch_in,0);//����o[0:Tm][:][:]
    int pingpong=0;
    for(int ch=Tm;ch<ch_out;ch+=Tm){
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
        if(pingpong==0){
        	compute_one_block(in1,in2,weight,obuffer2,fsize,ch_in,ch);//����o[ch:ch+Tm][:][:]
        	store_output(out,obuffer1,fsize-K+1,ch-Tm,pool);               //�洢o[0:Tm][:][:]
        	pingpong=1;
        }
        else{
        	compute_one_block(in1,in2,weight,obuffer1,fsize,ch_in,ch);
        	store_output(out,obuffer2,fsize-K+1,ch-Tm,pool);
        	pingpong=0;
        }
    }
    if(pingpong==1){
    	store_output(out,obuffer2,fsize-K+1,ch_out-Tm,pool);
    }
    else{
    	store_output(out,obuffer1,fsize-K+1,ch_out-Tm,pool);
    }
    //conv2d((volatile At*)in1,(volatile At*)in2,w,o,fsize,ch_in);
    //store_output((volatile Ot*)out,o,fsize-K+1,0);
}




